added SSCLI 1.0
[windows-sources.git] / sdk / samples / all in on code / Visual Studio 2008 / VBNamedPipeClient / ReadMe.txt
blob3c73b5b91e48b571185b8a1b48d9a3bd94a44d8f
1 ========================================================================
2     CONSOLE APPLICATION : VBNamedPipeClient Project Overview
3 ========================================================================
5 /////////////////////////////////////////////////////////////////////////////
6 Summary:
8 Named pipe is a mechanism for one-way or duplex inter-process communication 
9 between the pipe server and one or more pipe clients in the local machine or 
10 across the computers in the intranet:
12 PIPE_ACCESS_INBOUND:
13 Client (GENERIC_WRITE) ---> Server (GENERIC_READ)
15 PIPE_ACCESS_OUTBOUND:
16 Client (GENERIC_READ) <--- Server (GENERIC_WRITE)
18 PIPE_ACCESS_DUPLEX:
19 Client (GENERIC_READ or GENERIC_WRITE, or both) <--> 
20 Server (GENERIC_READ and GENERIC_WRITE)
22 This code sample demonstrate two methods to use named pipe in Visual C#.
24 1. Use the System.IO.Pipes namespace
26 The System.IO.Pipes namespace contains types that provide a means for 
27 interprocess communication through anonymous and/or named pipes. 
28 http://msdn.microsoft.com/en-us/library/system.io.pipes.aspx
29 These classes make the programming of named pipe in .NET much easier and 
30 safer than P/Invoking native APIs directly. However, the System.IO.Pipes 
31 namespace is not available before .NET Framework 3.5. So, if you are 
32 programming against .NET Framework 2.0, you have to P/Invoke native APIs 
33 to use named pipe.
35 The sample code in SystemIONamedPipeClient.Run() uses the 
36 Systen.IO.Pipes.NamedPipeClientStream class to connect to the named pipe 
37 "\\.\pipe\SamplePipe" to perform message-based duplex communication. 
38 The client then writes a message to the pipe and receives the response from the 
39 pipe server.
41 2. P/Invoke the native APIs related to named pipe operations.
43 The .NET interop services make it possible to call native APIs related to 
44 named pipe operations from .NET. The sample code in 
45 NativeNamedPipeClient.Run() demonstrates calling CreateFile to connect to 
46 the named pipe "\\.\pipe\SamplePipe" with the GENERIC_READ and 
47 GENERIC_WRITE accesses, and calling WriteFile and ReadFile to write a 
48 message to the pipe and receive the response from the pipe server. Please 
49 note that if you are programming against .NET Framework 3.5 or any newer 
50 releases of .NET Framework, it is safer and easier to use the types in the 
51 System.IO.Pipes namespace to operate named pipes.
54 /////////////////////////////////////////////////////////////////////////////
55 Demo:
57 The following steps walk through a demonstration of the named pipe sample.
59 Step1. After you successfully build the VBNamedPipeClient and 
60 VBNamedPipeServer sample projects in Visual Studio 2008, you will get the 
61 applications: VBNamedPipeClient.exe and VBNamedPipeServer.exe. 
63 Step2. Run VBNamedPipeServer.exe in a command prompt to start up the server 
64 end of the named pipe. If the command is "VBNamedPipeServer.exe", the pipe 
65 server is created by the types in the System.IO.Pipes namespace. If the 
66 command is "VBNamedPipeServer.exe -native", the pipe server is created by 
67 P/Invoking the native APIs related to named pipe operations. In both cases, 
68 the application outputs the following information in the command prompt if 
69 the pipe is created successfully.
71  Server:
72   The named pipe (\\.\pipe\SamplePipe) is created.
73   Waiting for the client's connection...
75 Step3. Run VBNamedPipeClient.exe in another command prompt to start up the 
76 client end of the named pipe. If the command is "VBNamedPipeClient.exe", the 
77 client connects to the pipe by using the types in the System.IO.Pipes 
78 namespace. If the command is "VBNamedPipeClient.exe -native", the client 
79 connects to the pipe by P/Invoking the native APIs related to named pipe 
80 operations. In both cases, the application should output the message below 
81 in the command prompt when the client successfully connects to the named pipe.
83  Client:
84   The named pipe (\\.\pipe\SamplePipe) is connected.
86 In the meantime, the server application outputs this message to indicate that 
87 the pipe is connected by a client.
89  Server:
90   Client is connected.
92 Step4. The client attempts to write a message to the named pipe. You will see 
93 the message below in the commond prompt running the client application.
95  Client:
96   Send 56 bytes to server: "Default request from client"
98 When the server application reads the message from the client, it prints:
100  Server:
101   Receive 56 bytes from client: "Default request from client"
103 Next, the server writes a response to the pipe.
105  Server:
106   Send 58 bytes to client: "Default response from server"
108 And the client receives the response:
110  Client:
111   Receive 58 bytes from server: "Default response from server"
113 The connection is disconnected and the pipe is closed after that.
116 /////////////////////////////////////////////////////////////////////////////
117 Sample Relation:
118 (The relationship between the current sample and the rest samples in 
119 Microsoft All-In-One Code Framework http://1code.codeplex.com)
121 VBNamedPipeClient -> CSNamedPipeServer/VBNamedPipeServer/CppNamedPipeServer
122 VBNamedPipeServer is the client end of the named pipe. CSNamedPipeServer, 
123 VBNamedPipeServer and CppNamedPipeServer can be the server ends that create 
124 the named pipe.
126 VBNamedPipeClient - CSNamedPipeClient - CppNamedPipeClient
127 VBNamedPipeClient, CSNamedPipeClient and CppNamedPipeServer are the same 
128 named pipe client ends written in three different programming languages.
131 /////////////////////////////////////////////////////////////////////////////
132 Code Logic:
134 A. Named pipe client by using the System.IO.Pipes namespace. 
135 (SystemIONamedPipeClient.Run())
137 1. Create a NamedPipeClientStream object and specify the pipe server, name, 
138 pipe direction, options, etc. 
140     pipeClient = New NamedPipeClientStream(Program.SERVER_NAME, _
141         Program.PIPE_NAME, PipeDirection.InOut, PipeOptions.None)
143 2. Connect to the named pipe by calling NamedPipeClientStream.Connect().
145     pipeClient.Connect(5000)
147 3. Set the read mode and the blocking mode of the named pipe. In this sample, 
148 we set data to be read from the pipe as a stream of messages. This allows a 
149 reading process to read varying-length messages precisely as sent by the 
150 writing process. In this mode, you should not use StreamWriter to write the 
151 pipe, or use StreamReader to read the pipe. You can read more about the 
152 difference from http://go.microsoft.com/?linkid=9721786.
154     pipeClient.ReadMode = PipeTransmissionMode.Message
156 4. Send a message to the pipe server and receive its response through 
157 NamedPipeClientStream.Read and NamedPipeClientStream.Write. Because 
158 pipeClient.ReadMode = PipeTransmissionMode.Message, you should not use 
159 StreamWriter to write the pipe, or use StreamReader to read the pipe.
161     '
162     ' Send a request from client to server.
163     '
165     Dim message As String = REQUEST_MESSAGE
166     Dim bRequest As Byte() = Encoding.Unicode.GetBytes(message)
167     Dim cbRequest As Integer = bRequest.Length
169     pipeClient.Write(bRequest, 0, cbRequest)
171     Console.WriteLine("Send {0} bytes to server: ""{1}""", _
172         cbRequest, message.TrimEnd(ControlChars.NullChar))
174     '
175     ' Receive a response from server.
176     '
178     Do
179         Dim bResponse(BUFFER_SIZE - 1) As Byte
180         Dim cbResponse As Integer = bResponse.Length, cbRead As Integer
182         cbRead = pipeClient.Read(bResponse, 0, cbResponse)
184         ' Unicode-encode the received byte array and trim all the '\0' 
185         ' characters at the end.
186         message = Encoding.Unicode.GetString(bResponse).TrimEnd( _
187             ControlChars.NullChar)
188         Console.WriteLine("Receive {0} bytes from server: ""{1}""", _
189             cbRead, message)
190     Loop While Not pipeClient.IsMessageComplete
192 5. Close the client end of the pipe by calling NamedPipeClientStream.Close().
194     pipeClient.Close()
196 -------------------------
198 B. Named pipe client by P/Invoke the native APIs related to named pipe 
199 operations. (NativeNamedPipeClient.Run())
201 1. Try to connect to a named pipe by P/Invoking CreateFile and specifying the 
202 target pipe server, name, desired access, etc. 
204     hNamedPipe = NativeMethod.CreateFile(FULL_PIPE_NAME, _
205         FileDesiredAccess.GENERIC_READ Or _
206         FileDesiredAccess.GENERIC_WRITE, _
207         FileShareMode.Zero, Nothing, _
208         FileCreationDisposition.OPEN_EXISTING, _
209         0, IntPtr.Zero)
211 If all pipe instances are busy, wait for 5 seconds and connect again.
213     If (Not NativeMethod.WaitNamedPipe(Program.FULL_PIPE_NAME, 5000)) Then
214         Throw New Win32Exception
215     End If
217 2. Set the read mode and the blocking mode of the named pipe. In this sample, 
218 we set data to be read from the pipe as a stream of messages.
220     Dim mode As PipeMode = PipeMode.PIPE_READMODE_MESSAGE
221     If (Not NativeMethod.SetNamedPipeHandleState(hNamedPipe, mode, _
222         IntPtr.Zero, IntPtr.Zero)) Then
223         Throw New Win32Exception
224     End If
226 3. Send a message to the pipe server and receive its response by calling 
227 the WriteFile and ReadFile functions.
229     '
230     ' Send a request from client to server.
231     '
233     Dim message As String = REQUEST_MESSAGE
234     Dim bRequest As Byte() = Encoding.Unicode.GetBytes(message)
235     Dim cbRequest As Integer = bRequest.Length, cbWritten As Integer
237     If (Not NativeMethod.WriteFile(hNamedPipe, bRequest, cbRequest, _
238         cbWritten, IntPtr.Zero)) Then
239         Throw New Win32Exception
240     End If
242     Console.WriteLine("Send {0} bytes to server: ""{1}""", _
243         cbWritten, message.TrimEnd(ControlChars.NullChar))
245     '
246     ' Receive a response from server.
247     '
249     Dim finishRead As Boolean = False
250     Do
251         Dim bResponse(BUFFER_SIZE - 1) As Byte
252         Dim cbResponse As Integer = bResponse.Length, cbRead As Integer
254         finishRead = NativeMethod.ReadFile(hNamedPipe, bResponse, _
255             cbResponse, cbRead, IntPtr.Zero)
257         If (Not finishRead _
258             AndAlso Marshal.GetLastWin32Error() <> ERROR_MORE_DATA) Then
259             Throw New Win32Exception
260         End If
262         ' Unicode-encode the received byte array and trim all the '\0' 
263         ' characters at the end.
264         message = Encoding.Unicode.GetString(bResponse).TrimEnd( _
265             ControlChars.NullChar)
266         Console.WriteLine("Receive {0} bytes from server: ""{1}""", _
267             cbRead, message)
269     Loop While Not finishRead   ' Repeat loop if ERROR_MORE_DATA
271 4. Close the pipe.
273     hNamedPipe.Close()
276 /////////////////////////////////////////////////////////////////////////////
277 References:
279 MSDN: System.IO.Pipes Namespace
280 http://msdn.microsoft.com/en-us/library/system.io.pipes.aspx
282 MSDN: NamedPipeClientStream
283 http://msdn.microsoft.com/en-us/library/system.io.pipes.namedpipeclientstream.aspx
285 How to: Use Named Pipes to Communicate Between Processes over a Network
286 http://msdn.microsoft.com/en-us/library/bb546085.aspx
288 Introducing Pipes [Justin Van Patten]
289 http://blogs.msdn.com/bclteam/archive/2006/12/07/introducing-pipes-justin-van-patten.aspx
292 /////////////////////////////////////////////////////////////////////////////